package com.jingdianjichi.club.gateway.filter;

import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaTokenConsts;
import cn.dev33.satoken.SaManager;
import com.alibaba.cloud.commons.lang.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.List;

@Slf4j
@Component
public class LoginIdTransferWebFilter implements WebFilter, Ordered {

    private static final List<String> WHITE_LIST = Arrays.asList(
            "/auth/user/doLogin","/auth/user/register","/auth/user/getCaptcha"
    );

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        String path = exchange.getRequest().getURI().getPath();
        log.info("请求过滤器开始执行, path={}, myOrder={}, SaTokenConsts.ASSEMBLY_ORDER={}", path, getOrder(), SaTokenConsts.ASSEMBLY_ORDER);
        if (WHITE_LIST.contains(path)) return chain.filter(exchange);

        try {
            // 显式从请求头获取 token，避免依赖 Reactor 上下文
            String tokenName = SaManager.getConfig().getTokenName();
            String token = exchange.getRequest().getHeaders().getFirst(tokenName);
            // 兜底从 Authorization 读取
            if (StringUtils.isBlank(token)) {
                String auth = exchange.getRequest().getHeaders().getFirst("Authorization");
                if (!StringUtils.isBlank(auth)) {
                    token = auth;
                }
            }
            log.info("从请求头解析出的 {} = {}", tokenName, token);
            if (StringUtils.isBlank(token)) throw new RuntimeException("no token");

            // 剥离可能存在的前缀：配置的 tokenPrefix 和常见的 Bearer
            String prefix = SaManager.getConfig().getTokenPrefix();
            if (!StringUtils.isBlank(prefix) && token.startsWith(prefix + " ")) {
                token = token.substring(prefix.length() + 1);
            }
            if (token.startsWith("Bearer ")) {
                token = token.substring(7);
            }

            Object loginIdObj = StpUtil.getLoginIdByToken(token);
            log.info("从 token 解析出的 loginId = {}", loginIdObj);
            String loginId = loginIdObj == null ? null : String.valueOf(loginIdObj);
            if (StringUtils.isBlank(loginId)) throw new RuntimeException("no loginId");

            ServerWebExchange mutated = exchange.mutate()
                    .request(exchange.getRequest().mutate().header("loginId", loginId).build())
                    .build();

            return chain.filter(mutated);
        } catch (Throwable e) {
            throw new RuntimeException("LoginIdTransferWebFilter.filter error, " + e.getMessage());
        }
    }


    @Override
    public int getOrder() {
        // 保证在 SaReactorFilter 之后执行（SaReactorFilter 使用框架常量）
        return SaTokenConsts.ASSEMBLY_ORDER + 1;
    }
}
